package game.ghostleg;

import java.util.LinkedList;
import java.util.concurrent.Semaphore;

public class GhostLegWorld {
	
	protected static int MAX_COL = 4;
	
	public PlayerInfo playerInfo;
	// number of players
	public int playerNum;
	// the start position of every player
	public int[] startPos;
	// the connection from each sources to their corresponding result
	// CAUTION : updated only at the last moment!
	public int[] result;
	// the items in each result
	public Item [] items;
	public Interval [] intervals;
	public boolean	isStartPosVisible,
					isItemsVisible;
	// end time, count in seconds
	public int time;
	public LinkedList<SocketData> inData, outData;
	Semaphore inLock, outLock;
	
	public void init() {
		playerInfo = new PlayerInfo();
		this.startPos	= new int[MAX_COL];
		this.items		= new Item[MAX_COL];
		this.intervals	= new Interval[MAX_COL-1];
		this.result		= new int[MAX_COL];
		for(int i=0;i<MAX_COL;i++)
			this.result[i] = i;
		this.inLock		= new Semaphore(1);
		this.outLock	= new Semaphore(1);
	}
	
	public GhostLegWorld(boolean isHost, PlayerInfo pPlayerInfo, int pPlayerNum) {
		super();
		init();
		
		this.playerInfo = pPlayerInfo;
		this.time		= 500;
		this.playerNum	= pPlayerNum;
		if ( isHost )
		{
			int i,j;
			// randomization
			for(i=0;i<MAX_COL;i++)
			{
				this.startPos[i]=i;
				j=(int)(Math.random()*MAX_COL);
				// perform swapping
				this.startPos[i]=this.startPos[i]^this.startPos[j];
				this.startPos[j]=this.startPos[i]^this.startPos[j];
				this.startPos[i]=this.startPos[i]^this.startPos[j];
				
				this.items[i]=Item.RandItem();
			}
			this.isStartPosVisible = this.isItemsVisible = true;
		}
		else
		{
			this.isItemsVisible		= false;
			this.isStartPosVisible	= false;
		}

	}

	public boolean insert ( int p_rowNum, int p_colNum, int p_playerNum ) {
		System.out.printf("In GhostLegWorld.Insert(%d,%d,%d), ",p_rowNum,p_colNum,p_playerNum);
		if ( 0 <= p_colNum && p_colNum < MAX_COL && 1 <= p_playerNum && p_playerNum <= this.playerNum )
		{
			System.out.println("Validation passed");
			return intervals[p_colNum].insert(p_rowNum, p_playerNum);
		}
		System.out.println("Failed : Out of range");
		return false;
	}

	public void computeResult() {
		int i,j,k;
		int tmp_result[] = new int[MAX_COL];
		for(i=0;i<Interval.MAX_ROW;i++)
		{
			for(j=0;j<MAX_COL;j++)
			{
				tmp_result[j]=j;
				if(j>0&&intervals[j-1].isConnected(i))
				{
					k=tmp_result[j-1];
					tmp_result[j-1]=tmp_result[j];
					tmp_result[j]=k;
				}
			}
			for(j=0;j<MAX_COL;j++)
				result[j]=tmp_result[result[j]];
		}
	}
	
}
